home *** CD-ROM | disk | FTP | other *** search
/ SGI Cosmo Software 1997 May / SGI Cosmo Software 1997 May.iso / dist / dist6.3 / java_dev.idb / usr / demos / java / Impression / Impression.java.z / Impression.java
Encoding:
Java Source  |  1997-05-24  |  9.2 KB  |  391 lines

  1. /*
  2.  *    impression -
  3.  *        This is a paint program that implements an Impressionist
  4.  *    painting technique based on image sampling.
  5.  *
  6.  *                Paul Haeberli - 1995
  7.  *                    paul@sgi.com
  8.  *
  9.  *             This painting technique is covered by 
  10.  *             U.S patent Number 5,182,548
  11.  *
  12.  */
  13. import java.awt.*;
  14. import java.lang.*;
  15. import java.net.*;
  16. import java.awt.image.*;
  17. import java.util.Random;
  18. import java.io.PrintStream;
  19.  
  20. class MemoryImage implements ImageConsumer {
  21.     boolean imgready;
  22.     int imgxsize, imgysize;
  23.     int imgpixels[][];
  24.  
  25.     MemoryImage(Image picture) {
  26.     int ticks;
  27.  
  28.     picture.getSource().startProduction(this);
  29.     ticks = 5*60*1000; /* 5 minutes */
  30.     while(ticks>0) {
  31.         try {
  32.         Thread.currentThread().sleep(100);
  33.         } catch (Exception e) { ; }
  34.         if(this.imgready)
  35.         break;
  36.         ticks -= 100;
  37.     }
  38.     }
  39.     public void setProperties(java.util.Hashtable dummy) {
  40.     }
  41.     public void setColorModel(ColorModel dummy) {
  42.     }
  43.     public void setHints(int dummy) {
  44.     }
  45.     public void imageComplete(int dummy) {
  46.     imgready = true;
  47.     }
  48.     public void setDimensions(int x, int y) {
  49.     imgxsize = x;
  50.     imgysize = y;
  51.     imgpixels = new int[y][x];
  52.     }
  53.     public void setPixels(int x1, int y1, int w, int h, 
  54.     ColorModel model, byte pixels[], int off, int scansize) {
  55.     int pix, x, y, x2, y2, sx, sy;
  56.  
  57.     x2 = x1+w;
  58.     y2 = y1+h;
  59.     sy = off;
  60.     for(y=y1; y<y2; y++) {
  61.         sx = sy;
  62.         for(x=x1; x<x2; x++) {
  63.         pix = model.getRGB(pixels[sx++]);
  64.         if((pix & 0xff000000) == 0)
  65.             pix = 0x00ffffff;
  66.         imgpixels[y][x] = pix;
  67.         }
  68.         sy += scansize;
  69.     }
  70.     }
  71.     public void setPixels(int x1, int y1, int w, int h, 
  72.     ColorModel model, int pixels[], int off, int scansize) {
  73.     int pix, x, y, x2, y2, sx, sy;
  74.  
  75.     x2 = x1+w;
  76.     y2 = y1+h;
  77.     sy = off;
  78.     for(y=y1; y<y2; y++) {
  79.         sx = sy;
  80.         for(x=x1; x<x2; x++) {
  81.         pix = model.getRGB(pixels[sx++]);
  82.         if((pix & 0xff000000) == 0)
  83.             pix = 0x00ffffff;
  84.         imgpixels[y][x] = pix;
  85.         }
  86.         sy += scansize;
  87.     }
  88.     }
  89. }
  90.  
  91. final public class Impression extends java.applet.Applet {
  92.     Random r;
  93.     Graphics canvasG, myG;
  94.     Image canvasimage, picture, menu;
  95.     int brushsize, paintmode;
  96.     int bsize, bsize2;
  97.     int jsize, jsize2;
  98.     int lx, ly, brushtype;
  99.     boolean lok;
  100.     MemoryImage memimg;
  101.     int wxsize, wysize;
  102.     int cxsize, cysize;
  103.     int dxsize, dysize;
  104.     boolean dopaint;
  105.     Font font;
  106.     FontMetrics fm;
  107.     Color border, canvas, text;
  108.     int nstrokes[] = { 5, 5, 5, 5, 10 };
  109.     int controlheight;
  110.     int borderwidth;
  111.     int brushsteps;
  112.  
  113.     public void init() {
  114.     controlheight = 30;
  115.     borderwidth = 1;
  116.     brushsteps = 8;
  117.     brushtype = 0;
  118.  
  119.     wxsize = size().width;
  120.     wysize = size().height;
  121.     cxsize = wxsize;
  122.     cysize = wysize-controlheight;
  123.     dxsize = cxsize-2*borderwidth;
  124.     dysize = cysize-2*borderwidth;
  125.  
  126.     resize(wxsize,wysize);
  127.  
  128.     canvasimage = createImage(dxsize,dysize);
  129.      myG = getGraphics();
  130.     canvasG = canvasimage.getGraphics();
  131.  
  132.     font = new java.awt.Font("TimesRoman", Font.ITALIC, 14);
  133.         canvasG.setFont(font);
  134.         fm = canvasG.getFontMetrics();
  135.         lok = false;
  136.     r = new Random();
  137.     setbrushsize(5);
  138.     paintmode = 1;
  139.     }
  140.     private int addjitter(int val) {
  141.     return val + (Math.abs(r.nextInt())%jsize) - jsize2;
  142.     }
  143.     private Color samplecolor(int x, int y) {
  144.     int pix;
  145.  
  146.     x = (x*memimg.imgxsize)/dxsize;
  147.     y = (y*memimg.imgysize)/dysize;
  148.     if(x<0) x = 0;
  149.     if(x>=memimg.imgxsize) x=memimg.imgxsize-1;
  150.     if(y<0) y = 0;
  151.     if(y>=memimg.imgysize) y=memimg.imgysize-1;
  152.     return new Color(memimg.imgpixels[y][x]);
  153.     }
  154.     private void drawbrush(Graphics g, int lx, int ly, int cx, int cy, int nsteps, boolean demo) {
  155.         int i, x, y, rx, ry, px, py, del;
  156.         int m, nmarks;
  157.  
  158.         for(i=0; i<nsteps; i++) {
  159.             px = (lx*(nsteps-i)+i*cx)/nsteps;
  160.             py = (ly*(nsteps-i)+i*cy)/nsteps;
  161.         if(demo) {
  162.         x = px;
  163.         y = py;
  164.         } else {
  165.         x = addjitter(px);
  166.         y = addjitter(py);
  167.         g.setColor(samplecolor(x,y));
  168.         }
  169.             switch(brushtype) {
  170.                 case 0:
  171.                     g.fillOval(x-bsize2,y-bsize2,bsize,bsize);
  172.                     break;
  173.                 case 1:
  174.             if(demo)
  175.             nmarks = 7;
  176.             else
  177.             nmarks = 1+(bsize*bsize)/200;
  178.                     for(m=0; m<nmarks; m++) {
  179.                         rx = addjitter(x);
  180.                         ry = addjitter(y);
  181.                         g.drawLine(rx-1,ry+1,rx+1,ry-1);
  182.                     }
  183.                     break;
  184.                 case 2:
  185.                     g.drawLine(x-bsize2,y+bsize2,x+bsize2,y-bsize2);
  186.                     break;
  187.                 case 3:
  188.             if(demo)
  189.             nmarks = 8;
  190.             else
  191.             nmarks = 2+(bsize)/3;
  192.             px = x-bsize2;        
  193.             py = y+bsize2;        
  194.                     for(m=0; m<nmarks; m++) {
  195.             del = (Math.abs(r.nextInt())%bsize);
  196.                 x = px + del;
  197.                 y = py - del;
  198.                         g.drawLine(x,y,x,y);
  199.                     }
  200.                     break;
  201.                 case 4:
  202.             g.drawLine(x,y,x,y);
  203.                     break;
  204.         }
  205.         }
  206.     }
  207.     private void showbrushsize() {
  208.     int xorg, yorg, mpos, barwidth, barheight, markwidth;
  209.  
  210.      xorg = 146;
  211.      yorg = cysize+10;
  212.      barwidth = 37;
  213.      barheight = 5;
  214.      markwidth = 3;
  215.        mpos = (int)((barwidth-markwidth)*(brushsize/(float)brushsteps));
  216.     myG.setColor(Color.white);
  217.     myG.fillRect(xorg,yorg,barwidth,barheight);
  218.     myG.setColor(Color.red);
  219.     myG.fillRect(xorg+mpos,yorg,markwidth,barheight);
  220.     }
  221.     private void showbrushtype() {
  222.     int xorg, yorg, oldsize;
  223.  
  224.     xorg = 277;
  225.     yorg = cysize+18;
  226.     oldsize = brushsize;
  227.     setbrushsize(3);
  228.     myG.setColor(Color.white);
  229.     myG.fillRect(xorg-15,yorg-15,30,30);
  230.     myG.setColor(Color.black);
  231.     drawbrush(myG,xorg,yorg,xorg,yorg,1,true);
  232.     setbrushsize(oldsize);
  233.     }
  234.     private void nextbrush() {
  235.     brushtype = (brushtype+1)%5;
  236.     showbrushtype();
  237.     }
  238.     private void setbrushsize(int newbrushsize) {
  239.     float diam;
  240.  
  241.     brushsize = newbrushsize;
  242.     diam = (int)(4.0*Math.pow(1.41,newbrushsize));
  243.     bsize2 = (int)(diam/2.0);
  244.     bsize = 2*bsize2+1;
  245.     jsize2 = (int)(2.0*diam/2.0);
  246.     jsize = 2*jsize2+1;
  247.     }
  248.     private void biggerbrush() {
  249.     if(brushsize<brushsteps) {
  250.         setbrushsize(brushsize+1);
  251.         showbrushsize();
  252.     }
  253.     }
  254.     private void smallerbrush() {
  255.     if(brushsize>0) {
  256.         setbrushsize(brushsize-1);
  257.         showbrushsize();
  258.     }
  259.     }
  260.     private void showtext(String word) {
  261.     canvasG.setColor(text);
  262.     canvasG.drawString(word,(wxsize-fm.stringWidth(word))/2, wysize/3);
  263.     }
  264.     private void clearscreen() {
  265.     canvasG.setColor(canvas);
  266.     canvasG.fillRect(0,0,dxsize,dysize);
  267.     switch(paintmode) {
  268.         case 1:
  269.         showtext("Loading image . . . ");
  270.         break;
  271.         case 2:
  272.         showtext("Paint Here to Reveal. . .");
  273.         break;
  274.     }
  275.     }
  276.     public void update(Graphics g) {
  277.     paint(g);
  278.     }
  279.     public boolean mouseDown(Event evt, int x, int y) {
  280.     if(x>0 && x<cxsize && y>0 && y<cysize) {
  281.         if(paintmode == 2) {
  282.         paintmode++;
  283.         clearscreen();
  284.         updatescreen(myG);
  285.         }
  286.         dopaint = true;
  287.         lok = false;
  288.     } else if(x>0 && x<cxsize && y>cysize+1 && y<wysize) {
  289.         if(x>0 && x<57) {
  290.         clearscreen();
  291.         updatescreen(myG);
  292.         } else if(x>80 && x<161)
  293.         smallerbrush();
  294.         else if(x>181 && x<259)
  295.         biggerbrush();
  296.         else if(x>261 && x<291)
  297.         nextbrush();
  298.     }
  299.     return true;
  300.     }
  301.     public boolean mouseUp(Event evt, int x, int y) {
  302.     dopaint = false;
  303.     return true;
  304.     }
  305.     public boolean mouseDrag(Event evt, int x, int y) {
  306.     if(dopaint) {
  307.         if(lok) {
  308.         if((lx == x) && (ly == y))
  309.             return true;
  310.         drawbrush(canvasG,lx,ly,x,y,nstrokes[brushtype],false);
  311.         updatescreen(myG);
  312.         } else {
  313.         lok = true;
  314.         }
  315.         lx = x;
  316.         ly = y;
  317.     }
  318.     return true;
  319.     }
  320.     public void updatescreen(Graphics g) {
  321.     g.drawImage(canvasimage,1,1,this);
  322.     }
  323.     private void updateall(Graphics g) {
  324.     g.setColor(border);
  325.     g.drawRect(0,0,cxsize-1,cysize-1);
  326.     g.setColor(Color.white);
  327.     g.fillRect(0,cysize,wxsize,controlheight);
  328.     updatescreen(g);
  329.     g.drawImage(menu,0,cysize+4,this);
  330.     }
  331.     private Color paramcolor(String name, Color defcolor) {
  332.     String pval;
  333.      Integer i;
  334.  
  335.     if((pval=getParameter(name)) != null) {
  336.         i = Integer.valueOf(pval,16);
  337.         return new Color(i.intValue());
  338.     } else {
  339.         return defcolor;
  340.     }
  341.     }
  342.     private URL FIXEDgetDocumentBase() {
  343.     String str;
  344.     int pos;
  345.     URL ret;
  346.  
  347.     str = getDocumentBase().toString();
  348.     pos =  str.indexOf((int)('?'));
  349.     if(pos>0) 
  350.         str = str.substring(0,pos);
  351.      try {
  352.         ret = new URL(str);
  353.         return ret;
  354.         } catch (Exception e) {
  355.             System.out.println("Malformed Docbase URL");
  356.         return null;
  357.         }
  358.     }
  359.     public void paint(Graphics g) {    
  360.     String sourcename;
  361.  
  362.     if(paintmode == 1) {
  363.         border = paramcolor("bordercolor", new Color(190,190,190));
  364.         canvas = paramcolor("canvascolor", new Color(231,215,199));
  365.         text = paramcolor("textcolor", new Color(20,20,20));
  366.         sourcename = getParameter("source");
  367.         clearscreen();
  368.         menu = getImage(getCodeBase(),"menu.gif");
  369.         updateall(g);
  370.         if(sourcename.startsWith("http://")) {
  371.         try {
  372.             picture = getImage(new URL(sourcename));
  373.         } catch (Exception e) { 
  374.             System.out.println("impression: bad URL spec");
  375.         }
  376.         } else {
  377.         picture = getImage(FIXEDgetDocumentBase(),sourcename);
  378.         }
  379.         memimg = new MemoryImage(picture);
  380.         if(memimg.imgpixels == null)
  381.         System.out.println("impression: error on image read!");
  382.         paintmode = 2;
  383.         clearscreen();
  384.         updatescreen(g);
  385.     } else 
  386.         updateall(g);
  387.     showbrushsize();
  388.     showbrushtype();
  389.     }
  390. }
  391.